//
//  HWOcrClientToken.m
//  OCR
//
//  Created by huawei on 2018/10/31.
//  Copyright © 2018/10/31 huawei. All rights reserved.
//

#import "HWOcrClientToken.h"
#import "HWOcrClientUtils.h"

@interface HWOcrClientToken()
@property (copy,nonatomic) NSString *domainName;
@property (copy,nonatomic) NSString *userName;
@property (copy,nonatomic) NSString *password;
@property (copy,nonatomic) NSString *region;
@property (copy,nonatomic) NSString *endPoint;
@property (copy,nonatomic) NSString *ocrToken;
@property (assign, nonatomic) int tokenCount;
@end

@implementation HWOcrClientToken

- (instancetype)initWithDomainName:(NSString *)domainName userName:(NSString *)userName password:(NSString *)password region:(NSString *)region {
    if (self = [super init]) {
        if ([HWOcrClientUtils isBlankString:domainName]) {
            NSLog(@"domainName cannot be empty");
            return nil;
        }
        if ([HWOcrClientUtils isBlankString:userName]) {
            NSLog(@"userName cannot be empty");
            return nil;
        }
        if ([HWOcrClientUtils isBlankString:password]) {
            NSLog(@"password cannot be empty");
            return nil;
        }
        if ([HWOcrClientUtils isBlankString:region]) {
            NSLog(@"region cannot be empty");
            return nil;
        }
        _domainName = domainName;
        _userName = userName;
        _password = password;
        _region = region;
        _endPoint = [NSString stringWithFormat:@"ocr.%@.myhuaweicloud.com", region];
        _tokenCount = 2;
        
        [self getOcrTokenAuth];
    }
    return self;
}

- (void) getOcrTokenAuth{
   
    if (_ocrToken) {
        return;
    }else{
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        NSDictionary *body = @{
                               @"auth":@{
                                       @"identity":@{
                                               @"methods":@[
                                                       @"password"
                                                       ],
                                               @"password":@{
                                                       @"user":@{
                                                               @"name":_userName,
                                                               @"password":_password,
                                                               @"domain":@{
                                                                       @"name":_domainName
                                                                       }
                                                               }
                                                       }
                                               },
                                       @"scope":@{
                                               @"project":@{
                                                       @"name":_region
                                                       }
                                               }
                                       }
                               };
        //URL
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://iam.%@.myhuaweicloud.com/v3/auth/tokens", self.region]]];
        [request setHTTPMethod:@"POST"];
        [request setTimeoutInterval:15.0f];
        request.allHTTPHeaderFields = @{@"Accept":@"application/json",@"Content-Type":@"application/json"};
        [request setHTTPBody:[[HWOcrClientUtils convertToJsonData:body] dataUsingEncoding:NSUTF8StringEncoding]];
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
        
        __weak typeof(self) weakSelf = self;
        NSURLSessionDataTask *sessionTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            weakSelf.tokenCount--;
            
            if (error) {
                if (weakSelf.tokenCount > 0) {
                    [self getOcrTokenAuth];
                } else {
                    NSLog(@"token get failure");
                    dispatch_semaphore_signal(semaphore);
                }
            }else{
                dispatch_semaphore_signal(semaphore);
                if([response isKindOfClass:[NSURLResponse class]])
                {
                    NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
                    weakSelf.ocrToken = r.allHeaderFields[@"X-Subject-Token"];
                }
            }
        }];
        [sessionTask resume];
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    }
}

- (void)refreshToken{
    _ocrToken = nil;
    [self getOcrTokenAuth ];
}

- (void)requestOcrServiceWithUri:(NSString *)uri
                           image: (UIImage *)image
                         options: (NSDictionary *)options
                  successHandler: (void (^)(id result))successHandler
                     failHandler: (void (^)(NSError* error, NSInteger errCode))failHandler{
    if ([HWOcrClientUtils isBlankString:uri]) {
        NSLog(@"uri cannot be empty ");
        return;
    }
    if (![image isKindOfClass:[UIImage class]] && options[@"url"] == nil) {
        NSLog(@"Should set image or the url of image");
        return;
    }
    if ([image isKindOfClass:[UIImage class]] && options[@"url"] != nil) {
        NSLog(@"Image or the url of image should be choose one");
        return;
    }
    NSString *url = [NSString stringWithFormat: @"https://%@%@",self.endPoint,uri];
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    if (image != nil) {
        NSString *image64 = [HWOcrClientUtils convertImageToBase64:image];
        [params setObject:image64 forKey:@"image"];
    }
    [params addEntriesFromDictionary:options];
    [self postUrl:url params:params successHandler:^(id result) {
        successHandler(result);
    } failHandler:^(NSError *error, NSInteger errCode) {
        failHandler(error, errCode);
    }];
    
}

// post request
- (void) postUrl:(NSString *)url params:(NSDictionary *)params
  successHandler: (void (^)(id result))successHandler
     failHandler: (void (^)(NSError* errMsg, NSInteger errCode))failHandler{
    
    __weak typeof(self) weakSelf = self;
    if (self.ocrToken) {
        [HWOcrClientUtils originalHttpPostRequestUrl:url params:params headers:@{@"Accept":@"application/json",@"Content-Type":@"application/json",@"X-Auth-Token":self.ocrToken} successHandler:^(id result) {

            NSError *err = nil;
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:&err];
            if ([dict[@"error_code"] integerValue] == 401 && [dict[@"error_msg"] isEqualToString:@"Token requires update"]) {

                [weakSelf refreshToken];
                [weakSelf postUrl:url params:params successHandler:^(id result) {
                    successHandler(result);
                } failHandler:^(NSError *err, NSInteger errCode) {
                    failHandler(err, errCode);
                }];
            } else {
                successHandler(result);
            }
        } failHandler:^(NSError *errMsg, NSInteger errCode) {
            failHandler(errMsg, errCode);
        }];
    } else {
        NSLog(@"token is Null");
        NSError *error = [[NSError alloc] init];
        failHandler(error, 50500);
    }
    
}

@end
